#pragma once

//基于阻塞队列 的 生产消费者模型
//cond mutex
#include <iostream>
#include <pthread.h>
#include <queue>
#include <unistd.h>

#define Num 5

template<class T>
class BlockQueue//阻塞队列,生产者与生产者互斥，消费者与消费者互斥，生产者与消费者互斥且同步
{
public:
    bool IsFull()
    {
        return _q.size()==_cap;
    }
    bool IsEmpty()
    {
        return _q.empty();
    }
public:
    BlockQueue(int cap=Num):_cap(cap)//构造函数-初始化阻塞队列
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_full,nullptr);
        pthread_cond_init(&_empty,nullptr);
    }        
    ~BlockQueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_full);
        pthread_cond_destroy(&_empty);
    }

    void Push(const T&data)//生产者生产数据
    {
        // pthread_mutex_lock(&mutex);
        lockGuard(&mutex);
        while(IsFull())
        {
            pthread_cond_wait(&_full,&_mutex);
        }
        _q.push(data);
    }
    void Pop(T& data)//消费者拿走数据
    {
        lockGuard(&mutex);
        while(IsEmpty())
        {
            pthread_cond_wait(&_empty,&mutex);
        }
        data=_q.front();
        _q.pop();
        
    }
private:
    std::queue<T> _q;//阻塞队列-是个临界资源，需要用锁维护
    int _cap;//阻塞队列中最大容器数据个数
    pthread_mutex_t _mutex;
    pthread_cond_t _full;//条件变量-满
    pthread_cond_t _empty;//条件变量-空
};